<?php

namespace app\portal\controller;

use app\admin\model\Question;
use app\common\controller\PortalBase;
use think\Exception;
use think\Request;
use think\Config;

class Test extends PortalBase {
  protected $model, $modelTestAnswer, $modelQuestion;

  public function __construct(Request $request = NULL) {
    parent::__construct($request);
    $this->model = new \app\admin\model\Test();
    $this->modelTestAnswer = new \app\admin\model\TestAnswer();
    $this->modelQuestion = new Question();
  }

  public function _initialize() {
    parent::_initialize();
  }

  public function index() {

  }


  public function view() {
    $nowTimestamp = time();
    //查找是否有未结束的考卷
    $map = [
      'status' => ['<=',
                   0],
      'uid'    => $this->uid,
    ];
    $testAnswer = $this->modelTestAnswer->where($map)->find();
    if (!$testAnswer) $this->error('当前没有为您生成考卷，请从正确的路径进入系统');
    $paper = [];
    $testAnswerId = $testAnswer['id'];
    if ($testAnswer['status'] == -1) {//接着开始
      $paper = $this->model->find($testAnswer['paper_id']);
      $endTimestamp = $nowTimestamp + $paper['exam_duration'] * 60;
      $startTime = date('Y-m-d H:i:s', $nowTimestamp);
      $endTime = date('Y-m-d H:i:s', $endTimestamp);
      $data = [
        'start_time' => $startTime,
        'end_time'   => $endTime,
        'status'     => 0,
      ];
      try {
        $this->modelTestAnswer->save($data, ['id' => $testAnswer['id']]);
      } catch (Exception $e) {
        $this->error($e->getMessage());
      }
    } elseif (strtotime($testAnswer['end_time']) < $nowTimestamp) {      //过时间的自动结束
      $data = ['status' => 1];
      $map = ['id' => $testAnswer['id']];
      $this->modelTestAnswer->save($data, $map);
      $this->result([], -1, '您的考卷已经超出考试时间，自动结束，请重新开始考试');

    } else { //接着开始
      $paper = $this->model->find($testAnswer['paper_id']);
      $startTime = $testAnswer['start_time'];
      $endTime = $testAnswer['end_time'];
      $endTimestamp = strtotime($endTime);
    }


    $questions = json_decode($paper['questions'], TRUE);

    $cursorMax = count($questions);//最大游标
    $cursors = json_encode(range(1, $cursorMax));
    //计算结束时间
    $overplusTime = $endTimestamp - $nowTimestamp;
    if ($overplusTime > 0) {
      $minute = floor($overplusTime / 60);
      $second = $overplusTime % 60;
    } else {
      $minute = $second = 0;
    }
    $examFinish = $overplusTime <= 0 ? 1 : 0;
    $returnData = [
      'cursorMax'    => $cursorMax,
      'cursor'       => $testAnswer ? $testAnswer['cursor'] : 0,
      'cursors'      => $cursors,
      'paperId'      => $paper['id'],
      'nowTime'      => date('H:i:s', $nowTimestamp),
      'nowTimestamp' => $nowTimestamp,
      'minute'       => $minute,
      'second'       => $second,
      'examFinish'   => $examFinish,
      'testAnswerId' => $testAnswerId,
      'passScore'    => $paper['pass_score'],
    ];
    cmf_log('开始模拟考试', $paper['id'], date('Y-m-d H:i'));

    if (request()->isAjax()) {
      $this->result($returnData, 1);
    }

    return view('', $returnData);
  }

  public function view_pre() {
    $nowTimestamp = time();
    //查找是否有未结束的考卷
    $map = [
      'status' => 0,
      'uid'    => $this->uid,
    ];
    $testAnswer = $this->modelTestAnswer->where($map)->find();
    $paper = [];
    $testUnfinish = FALSE;;
    //没有未完成的考卷
    if ($testAnswer) {
      if (strtotime($testAnswer['end_time']) < $nowTimestamp) {      //过时间的自动结束
        $data = ['status' => 1];
        $map = ['id' => $testAnswer['id']];
        $this->modelTestAnswer->save($data, $map);
      } else { //接着开始
        $testUnfinish = TRUE;
        $paper = $this->model->find($testAnswer['paper_id']);
        $startTime = $testAnswer['start_time'];
        $endTime = $testAnswer['end_time'];
        $endTimestamp = strtotime($endTime);
        $testAnswerId = $testAnswer['id'];
      }
    }
    if (!$testUnfinish) {
      $paper = $this->model->where('status', 0)->orderRaw('rand()')->find();
      if (!$paper) $this->error('当前没有模拟考卷');
      $endTimestamp = $nowTimestamp + $paper['exam_duration'] * 60;
      $startTime = date('Y-m-d H:i:s', $nowTimestamp);
      $endTime = date('Y-m-d H:i:s', $endTimestamp);
      $data = [
        'paper_id' => $paper['id'],
        'uid'      => $this->uid,
        'status'   => -1,
      ];
      try {
        $this->modelTestAnswer->isUpdate(FALSE)->save($data);
      } catch (Exception $e) {
        $this->error($e->getMessage());
      }
      $testAnswerId = $this->modelTestAnswer->id;

    }

    $returnData = [
      'cursor'        => $testAnswer ? $testAnswer['cursor'] : 0,
      'paperId'       => $paper['id'],
      'nowTime'       => date('H:i:s', $nowTimestamp),
      'nowTimestamp'  => $nowTimestamp,
      'testAnswerId'  => $testAnswerId,
      'qExamDuration' => $paper['exam_duration'],
      'passScore'     => $paper['pass_score'],
      'qConfig'       => $paper['q_config'],
      'qType'         => config('question')['type'],
    ];

    if (request()->isAjax()) {
      $this->result($returnData, 1);
    }

    $this->redirect('view');

  }

  public function getPaperQuestions() {
    $paperId = input('paper_id', 0);
    $cursor = input('cursor/d', 0);
    $paper = ($paperId > 0) ? $this->model->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    $map = [
      'uid'      => $this->uid,
      'paper_id' => $paperId,
      'status'   => 0,
    ];
    $testAnswer = $this->modelTestAnswer->where($map)->find();
    //返回所有问题的数据
    $paperQuestionIDs = json_decode($paper['questions'], TRUE);
    $paperQuestions = $this->modelQuestion
      ->where('id', 'in', $paperQuestionIDs)
      ->column('content,answers,type', 'id');
    //返回所有问题的答案
    $paperAnswers = json_decode($testAnswer['answers'], TRUE);
    //返回所有的标记
    $paperSign = json_decode($testAnswer['sign'], TRUE);
    $active = -1;
    if ($paperAnswers) {
      $active = $paperAnswers[ $cursor ];
    } else {
      $paperAnswers = [];
    }
    //获取题目类型type
    $questionTypeCount = [];
    foreach ($paperQuestions as $q) {
      $questionTypeCount[ $q['type'] ] += 1;
    }
    //返回数据
    $data = [
      'question'          => $paperQuestions[0],
      'paperQuestionIDs'  => $paperQuestionIDs,
      'paperQuestions'    => $paperQuestions,
      'paperSign'         => $paperSign ? $paperSign : [],
      'active'            => $active,
      'paperAnswers'      => $paperAnswers,
      'examFinish'        => $testAnswer['status'],
      'questionTypeCount' => $questionTypeCount,
    ];
    $this->result($data, 1);
  }

  public function doAnswer() {
    $id = input('id/d', 0);
    $cursor = input('cursor/d', 0);
    $answer = input('answer/d', 0);

    $testAnswer = $this->modelTestAnswer->find($id);

    if ($testAnswer['status'] != 0)
      $this->error('错误，试卷已经完成了，不能提交答案');
    //
    $nowTimestamp = time();
    if ($nowTimestamp > strtotime($testAnswer['end_time'])) {
      $this->finish($id);

      return FALSE;
    }
    $answers = json_decode($testAnswer['answers'], TRUE);
    $answers[ $cursor ] = $answer;
    $data = [
      'answers' => json_encode($answers),
      'cursor'  => $cursor,
    ];
    $r = $this->modelTestAnswer->save($data, ['id' => $id]);
    if ($r === FALSE) $this->error(lang('error') . $this->modelTestAnswer->getError());
    $this->success();
  }

  public function signQuestion() {
    $id = input('id/d', 0);
    $cursor = input('cursor/d', 0);
    $testAnswer = ($id > 0) ? $this->modelTestAnswer->find($id) : NULL;
    if (!$testAnswer)
      $this->error(lang('paper empty') . $id);
    if ($testAnswer['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    $sign = json_decode($testAnswer['sign'], TRUE);
    if (!$sign) {
      $sign[ $cursor ] = 1;
    } else {
      $sign[ $cursor ] = !$sign[ $cursor ];
    }

    $data = [
      'sign' => json_encode($sign),
    ];
    $r = $this->modelTestAnswer->save($data, ['id' => $id]);
    if ($r !== FALSE)
      $this->success();
    $this->error();
  }

  public function finish($id = 0) {
    $id = input('id', $id, 'abs');
    $testAnswer = ($id > 0) ? $this->modelTestAnswer->find($id) : NULL;
    if (!$testAnswer)
      $this->error('考试不存在');
    $paper = $this->model->find($testAnswer['paper_id']);
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($testAnswer['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    if ($testAnswer['status'] != 0)
      $this->error('错误，试卷已经完成了，不能再次提交');
    $qConfig = json_decode($paper['q_config'], TRUE);
    $questions = json_decode($paper['questions'], TRUE);
    $answers = json_decode($testAnswer['answers'], TRUE);

    $qInfo = $this->modelQuestion->getQuestion($questions);

    $rightCount = 0;
    $score = 0;
    foreach ($questions as $key => $qid) {
      if ($qInfo[ $qid ]['right'] === $answers[ $key ]) {
        $type = $qInfo[ $qid ]['type'];
        $rightCount += 1;
        $score += $qConfig[ $type ]['score'];
      }
    }
    //排名
    $map = [
      'paper_id' => $testAnswer['paper_id'],
      'status'   => 1,
      'score'    => ['<',
                     $score],
    ];
    $scoreSort = $this->modelTestAnswer->where($map)->count();
    //交卷
    $data = [
      'status'      => 1,
      'right_count' => $rightCount,
      'score'       => $score,
      'score_sort'  => $scoreSort,
    ];
    //事务
    $this->modelTestAnswer->startTrans();
    try {
      $this->modelTestAnswer->save($data, ['id' => $id]);
      $this->modelTestAnswer->commit();
    } catch (\Exception $e) {
      $this->modelTestAnswer->rollback();
      $this->error($e->getMessage());
    }
    //
    $returnData = ['score'       => (int)$score,
                   'right_count' => $rightCount,
                   'score_sort'  => $scoreSort,
    ];

    cmf_log('结束模拟考试', $id, date('Y-m-d H:i'));
    $this->success("本场考试得分要求为{$paper['pass_score']}分,您的得分是{$score}分,击败了{$scoreSort}名对手。", NULL, $returnData);
  }

}